package edu.xpu.compute.recommend.restful;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import edu.xpu.compute.recommend.algorithm.CollaborativeFilterAlgorithm;
import edu.xpu.compute.recommend.common.model.ResponseParam;
import edu.xpu.compute.recommend.entity.SysBook;
import edu.xpu.compute.recommend.entity.SysUser;
import edu.xpu.compute.recommend.service.SysBookService;
import edu.xpu.compute.recommend.service.SysUserService;
import edu.xpu.compute.recommend.vo.CfAlgorithmAnalyseParamVo;
import edu.xpu.compute.recommend.vo.CfAlgorithmAnalyseResultVo;

/**
 * 协同过滤算法分析接口
 * @author liukang
 * @date 2019年10月31日
 */
@RequestMapping(value="restful/algorithm/cf")
@RestController
public class CollaborativeFilterRestful {
	@Autowired
	private CollaborativeFilterAlgorithm collaborativeFilterAlgorithm;
	@Autowired
	private SysBookService bookService;
	@Autowired
	private SysUserService sysUserService;
	
	/**
	 * 基于图书的协同过滤
	 * @param analyseParamVo
	 * @return
	 */
	@PostMapping(value="itemBasedRecommender")
	public ResponseParam<CfAlgorithmAnalyseResultVo> itemBasedRecommender(@RequestBody CfAlgorithmAnalyseParamVo analyseParamVo) {
		CfAlgorithmAnalyseResultVo cfAlgorithmAnalyseResultVo = new CfAlgorithmAnalyseResultVo();
		/*
		 * 获取用户信息
		 */
		Long userGuid = analyseParamVo.getUserGuid();
		if (userGuid == null) {
			return new ResponseParam<CfAlgorithmAnalyseResultVo>("用户id为空, 请选择用户!", 500);
		}
		SysUser sysUser = sysUserService.get(userGuid);
		cfAlgorithmAnalyseResultVo.setUserGuid(userGuid);
		if (sysUser != null) {
			cfAlgorithmAnalyseResultVo.setUserName(sysUser.getName());
		}
		try {
			List<Long> list = null;
			try {
				list = collaborativeFilterAlgorithm.itemBasedRecommender(analyseParamVo.getUserGuid(),
						analyseParamVo.getMaxSize(), analyseParamVo.getSimilarityType());
			} catch (Exception e) {
				return new ResponseParam<CfAlgorithmAnalyseResultVo>("评分数据缺失，推荐失败！", 500);
			}
			if (list != null && list.size() != 0) {
				cfAlgorithmAnalyseResultVo.setBookNum(list.size());
				List<SysBook> books = new ArrayList<SysBook>();
				for (Long bookGuid : list) {
					SysBook sysBook = bookService.get(bookGuid);
					if (sysBook != null) {
						books.add(sysBook);
					}
				}
				cfAlgorithmAnalyseResultVo.setBooks(books);
			}
		} catch (Exception e) {
			return new ResponseParam<CfAlgorithmAnalyseResultVo>("分析过程中出现异常，推荐失败！", 500);
		}
		return new ResponseParam<CfAlgorithmAnalyseResultVo>("获取推荐结果成功", 200, cfAlgorithmAnalyseResultVo);
	}
	
	/**
	 * 基于用户的协同过滤
	 * @param analyseParamVo
	 * @return
	 */
	@PostMapping(value="userBasedRecommender")
	public ResponseParam<CfAlgorithmAnalyseResultVo> userBasedRecommender(@RequestBody CfAlgorithmAnalyseParamVo analyseParamVo) {
		CfAlgorithmAnalyseResultVo cfAlgorithmAnalyseResultVo = new CfAlgorithmAnalyseResultVo();
		/*
		 * 获取用户信息
		 */
		Long userGuid = analyseParamVo.getUserGuid();
		if (userGuid == null) {
			return new ResponseParam<CfAlgorithmAnalyseResultVo>("用户id为空, 请选择用户!", 500);
		}
		SysUser sysUser = sysUserService.get(userGuid);
		cfAlgorithmAnalyseResultVo.setUserGuid(userGuid);
		if (sysUser != null) {
			cfAlgorithmAnalyseResultVo.setUserName(sysUser.getName());
		}
		try {
			List<Long> list = null;
			try {
				list = collaborativeFilterAlgorithm.userBasedRecommender(analyseParamVo.getUserGuid(),
						analyseParamVo.getMaxSize(), analyseParamVo.getSimilarityType());
			} catch (Exception e) {
				return new ResponseParam<CfAlgorithmAnalyseResultVo>("评分数据缺失，推荐失败！", 500);
			}
			if (list != null && list.size() != 0) {
				cfAlgorithmAnalyseResultVo.setBookNum(list.size());
				List<SysBook> books = new ArrayList<SysBook>();
				for (Long bookGuid : list) {
					SysBook sysBook = bookService.get(bookGuid);
					if (sysBook != null) {
						books.add(sysBook);
					}
				}
				cfAlgorithmAnalyseResultVo.setBooks(books);
			}
		} catch (Exception e) {
			return new ResponseParam<CfAlgorithmAnalyseResultVo>("分析过程中出现异常，推荐失败！", 500);
		}
		return new ResponseParam<CfAlgorithmAnalyseResultVo>("获取推荐结果成功", 200, cfAlgorithmAnalyseResultVo);
	}

}
